#include <string>
#include <iostream>
#include <unordered_map>
#include <functional>
using namespace std;

#include "include/muduo/net/TcpServer.h"
#include "include/muduo/net/EventLoop.h"
#include "include/muduo/net/TcpConnection.h"

// 词典服务器类
// 启动服务器后进行事件监控->建立连接/关闭连接或收到消息时，调用设置的回调函数进行响应
class TranslateServer
{
public:
    TranslateServer(int port): _server(&_baseloop, 
        muduo::net::InetAddress("0.0.0.0", port), 
        "TranslateServer", muduo::net::TcpServer::Option::kReusePort)
        {
            // 将成员函数设置作为服务器的回调
            _server.setConnectionCallback(std::bind(&TranslateServer::onConnectionCallBack, this, std::placeholders::_1));
            _server.setMessageCallback(std::bind(&TranslateServer::onMessageCallBack, this, std::placeholders::_1, 
                std::placeholders::_2, std::placeholders::_3));
        }

    // 启动服务器
    void Start()
    {
        _server.start(); // 开始事件监听
        _baseloop.loop(); // 开始事件监控，死循环
    }
private:

    // 建立连接成功/关闭连接时的回调
    void onConnectionCallBack(const muduo::net::TcpConnectionPtr& conn)
    {
        if(conn->connected() == true)
        {
            std::cout << "建立新连接成功" << std::endl;
        }
        else
        {
            std::cout << "关闭连接成功" << std::endl;
        }
    }
    string translate(const string& str)
    {
        static unordered_map<string, string> map = {
            {"hello", "你好"},
            {"string", "字符串"},
            {"wangshu", "大帅b"}
        };
        if(map.find(str) == map.end())
        {
            return "找不到捏";
        }
        return map[str];
    }
    // 通信连接收到请求时的回调
    void onMessageCallBack(const muduo::net::TcpConnectionPtr& conn, muduo::net::Buffer* buffer, muduo::Timestamp)
    {
        // 从buffer中取出请求数据
        string req = buffer->retrieveAllAsString();
        // 业务处理逻辑
        string resp = translate(req);
        // 将响应返回到连接
        conn->send(resp);
    }
    
private:
    muduo::net::EventLoop _baseloop;
    muduo::net::TcpServer _server;
};

int main()
{
    TranslateServer server(8088);
    server.Start();
    return 0;
}